package org.example.rubbish.controller;

import org.example.rubbish.dto.AlarmDTO;
import org.example.rubbish.dto.DatabaseAlarmRequest;
import org.example.rubbish.entity.Alarm;
import org.example.rubbish.service.AlarmService;
import org.example.rubbish.service.UnifiedWebSocketService;
import org.example.rubbish.websocket.TerminalWebSocketServer;
import org.example.rubbish.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/alarm")
@CrossOrigin(origins = "*")
public class AlarmController {

    @Autowired
    private AlarmService alarmService;

    @Autowired
    private WebSocketServer webSocketServer;

    @Autowired
    private UnifiedWebSocketService unifiedWebSocketService;

    @Autowired
    private TerminalWebSocketServer terminalWebSocketServer;

    /**
     * 接收报警信息
     */
    @PostMapping("/receive")
    public ApiResponse<String> receiveAlarm(@RequestBody AlarmDTO alarmDTO) {
        System.out.println("📥 收到报警 DTO: " + alarmDTO);
        boolean saveOk = alarmService.processNewAlarm(alarmDTO);
        if (saveOk) {
            System.out.println("✅ 保存成功，马上广播 >>>");
            webSocketServer.broadcastAlarm(alarmDTO);   // 就是这里
            System.out.println("📢 广播完成，ID=" + alarmDTO.getAlarmId());
            return ApiResponse.success("ok");
        }
        return ApiResponse.error("save failed");
    }

    /**
     * 确认报警 - 路径参数方式
     */
    @PostMapping("/acknowledge/{alarmId}")
    public ApiResponse<String> acknowledgeAlarm(@PathVariable String alarmId,
                                                @RequestParam String acknowledgedBy) {
        boolean success = alarmService.acknowledgeAlarm(alarmId, acknowledgedBy);
        if (success) {
            return ApiResponse.success("报警确认成功");
        } else {
            return ApiResponse.error("报警确认失败");
        }
    }

    /**
     * 确认报警 - 请求体方式
     */
    @PostMapping("/ack")
    public ApiResponse<String> acknowledgeAlarm(@RequestBody Map<String, String> requestData) {
        try {
            String alarmId = requestData.get("alarmId");
            String acknowledgedBy = requestData.get("acknowledgedBy");

            if (alarmId == null || acknowledgedBy == null) {
                return ApiResponse.error("报警ID和确认人不能为空");
            }

            boolean success = alarmService.acknowledgeAlarm(alarmId, acknowledgedBy);
            if (success) {
                return ApiResponse.success("报警确认成功");
            } else {
                return ApiResponse.error("报警确认失败，报警不存在或已被确认");
            }
        } catch (Exception e) {
            return ApiResponse.error("报警确认失败: " + e.getMessage());
        }
    }

    /**
     * 获取未确认报警列表
     */
    @GetMapping("/unacknowledged")
    public ApiResponse<List<Alarm>> getUnacknowledgedAlarms() {
        List<Alarm> alarms = alarmService.getUnacknowledgedAlarms();
        return ApiResponse.success(alarms);
    }

    /**
     * 模拟报警生成（测试用）
     */
    @PostMapping("/test/generate")
    public ApiResponse<String> generateTestAlarm() {
        try {
            AlarmDTO testAlarm = new AlarmDTO(
                    "TEST_" + System.currentTimeMillis(),
                    "测试报警",
                    "这是一个测试报警信息，用于验证系统功能",
                    "test_system",
                    "MEDIUM",
                    "SOFTWARE",
                    null
            );

            alarmService.processNewAlarm(testAlarm);
            return ApiResponse.success("测试报警生成成功");
        } catch (Exception e) {
            return ApiResponse.error("测试报警生成失败: " + e.getMessage());
        }
    }

    /**
     * 通过WebSocket模拟报警（测试用）
     */
    @PostMapping("/test/websocket/generate")
    public ApiResponse<String> generateWebSocketTestAlarm() {
        try {
            AlarmDTO testAlarm = new AlarmDTO(
                    "WS_TEST_" + System.currentTimeMillis(),
                    "WebSocket测试报警",
                    "这是一个通过WebSocket发送的测试报警信息",
                    "websocket_test",
                    "HIGH",
                    "WEBSOCKET",
                    Map.of("testType", "websocket", "timestamp", System.currentTimeMillis())
            );

            // 通过WebSocket广播报警
            webSocketServer.broadcastAlarm(testAlarm);
            return ApiResponse.success("WebSocket测试报警发送成功");
        } catch (Exception e) {
            return ApiResponse.error("WebSocket测试报警发送失败: " + e.getMessage());
        }
    }

    /**
     * 获取WebSocket连接状态
     */
    @GetMapping("/websocket/status")
    public ApiResponse<Map<String, Object>> getWebSocketStatus() {
        try {
            Map<String, Object> status = Map.of(
                    "connectionCount", webSocketServer.getConnectionCount(),
                    "status", "running",
                    "timestamp", System.currentTimeMillis()
            );
            return ApiResponse.success(status);
        } catch (Exception e) {
            return ApiResponse.error("获取WebSocket状态失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有客户端连接状态
     */
    @GetMapping("/websocket/connections")
    public ApiResponse<UnifiedWebSocketService.ConnectionStats> getConnectionStats() {
        try {
            UnifiedWebSocketService.ConnectionStats stats = unifiedWebSocketService.getConnectionStats();
            return ApiResponse.success(stats);
        } catch (Exception e) {
            return ApiResponse.error("获取连接状态失败: " + e.getMessage());
        }
    }

    /**
     * 发送测试报警到终端
     */
    @PostMapping("/test/terminal/send")
    public ApiResponse<String> sendTestAlarmToTerminal(@RequestBody Map<String, String> request) {
        try {
            String terminalId = request.get("terminalId");
            String title = request.get("title");

            if (terminalId == null || title == null) {
                return ApiResponse.error("terminalId和title不能为空");
            }

            AlarmDTO testAlarm = new AlarmDTO(
                    "TERMINAL_TEST_" + System.currentTimeMillis(),
                    title,
                    "这是发送给终端的测试报警",
                    "terminal_test",
                    "MEDIUM",
                    "TEST",
                    Map.of("target", terminalId, "timestamp", System.currentTimeMillis())
            );

            // 发送给特定终端
            terminalWebSocketServer.sendAlarmToTerminal(terminalId, testAlarm);
            return ApiResponse.success("测试报警发送成功");
        } catch (Exception e) {
            return ApiResponse.error("发送测试报警失败: " + e.getMessage());
        }
    }

    /**
     * 从数据库获取真实报警数据发送给特定终端
     */
    @PostMapping("/database/send-to-terminal")
    public ApiResponse<String> sendDatabaseAlarmsToTerminal(@RequestBody DatabaseAlarmRequest request) {
        try {
            String terminalId = request.getTerminalId();
            if (terminalId == null) {
                return ApiResponse.error("terminalId不能为空");
            }

            // 从数据库获取真实的报警数据
            List<AlarmDTO> alarms = alarmService.getAlarmsFromDatabase(
                    request.getHours(),
                    request.getAcknowledged(),
                    request.getLimit(),
                    request.getSource(),
                    request.getLevel()
            );

            if (alarms.isEmpty()) {
                return ApiResponse.success("没有找到符合条件的报警数据");
            }

            // 发送给特定终端
            for (AlarmDTO alarm : alarms) {
                terminalWebSocketServer.sendAlarmToTerminal(terminalId, alarm);
            }

            return ApiResponse.success("成功发送 " + alarms.size() + " 条真实报警数据到终端");

        } catch (Exception e) {
            return ApiResponse.error("发送数据库报警失败: " + e.getMessage());
        }
    }

    /**
     * 从数据库获取真实报警数据广播给所有终端
     */
    @PostMapping("/database/broadcast-to-terminals")
    public ApiResponse<String> broadcastDatabaseAlarmsToTerminals(@RequestBody DatabaseAlarmRequest request) {
        try {
            // 从数据库获取真实的报警数据
            List<AlarmDTO> alarms = alarmService.getAlarmsFromDatabase(
                    request.getHours(),
                    request.getAcknowledged(),
                    request.getLimit(),
                    request.getSource(),
                    request.getLevel()
            );

            if (alarms.isEmpty()) {
                return ApiResponse.success("没有找到符合条件的报警数据");
            }

            // 广播给所有终端
            for (AlarmDTO alarm : alarms) {
                terminalWebSocketServer.broadcastAlarm(alarm);
            }

            return ApiResponse.success("成功广播 " + alarms.size() + " 条真实报警数据到所有终端客户端");

        } catch (Exception e) {
            return ApiResponse.error("广播数据库报警失败: " + e.getMessage());
        }
    }

    /**
     * 获取最近未确认的报警数据（用于调试）
     */
    @GetMapping("/database/recent-unacknowledged")
    public ApiResponse<List<AlarmDTO>> getRecentUnacknowledgedAlarms(
            @RequestParam(defaultValue = "24") int hours) {
        try {
            List<AlarmDTO> alarms = alarmService.getRecentUnacknowledgedAlarms(hours);
            return ApiResponse.success(alarms);
        } catch (Exception e) {
            return ApiResponse.error("获取报警数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取终端连接状态
     */
    @GetMapping("/terminal/connections")
    public ApiResponse<Map<String, Object>> getTerminalConnections() {
        try {
            Map<String, Object> status = Map.of(
                    "connectionCount", terminalWebSocketServer.getConnectionCount(),
                    "onlineTerminals", terminalWebSocketServer.getOnlineTerminals(),
                    "timestamp", System.currentTimeMillis()
            );
            return ApiResponse.success(status);
        } catch (Exception e) {
            return ApiResponse.error("获取终端连接状态失败: " + e.getMessage());
        }
    }

    // 统一的API响应格式
    public static class ApiResponse<T> {
        private boolean success;
        private String message;
        private T data;

        public static <T> ApiResponse<T> success(T data) {
            ApiResponse<T> response = new ApiResponse<>();
            response.setSuccess(true);
            response.setMessage("成功");
            response.setData(data);
            return response;
        }

        public ApiResponse() {
        }

        public static <T> ApiResponse<T> error(String message) {
            ApiResponse<T> response = new ApiResponse<>();
            response.setSuccess(false);
            response.setMessage(message);
            return response;
        }

        public ApiResponse(boolean success, String message, T data) {
            this.success = success;
            this.message = message;
            this.data = data;
        }

        public boolean isSuccess() {
            return success;
        }

        public void setSuccess(boolean success) {
            this.success = success;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }
    }
}